/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package exterminator.states;

import com.jme3.app.state.AbstractAppState;
import com.jme3.font.BitmapFont.Align;
import com.jme3.font.BitmapFont.VAlign;
import com.jme3.font.LineWrapMode;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector4f;
import com.jme3.texture.Texture;
import exterminator.Main;
import exterminator.game.Game.Lost;
import exterminator.utils.TextureManager.RegionKey;
import exterminator.utils.TextureManager.TextureKey;
import tonegod.gui.controls.buttons.Button;
import tonegod.gui.controls.buttons.ButtonAdapter;
import tonegod.gui.controls.buttons.RadioButtonGroup;
import tonegod.gui.controls.extras.Indicator;
import tonegod.gui.controls.text.TextElement;
import tonegod.gui.core.Element;
import tonegod.gui.core.Element.Orientation;
import tonegod.gui.core.Screen;
import tonegod.gui.core.utils.UIDUtil;
import tonegod.gui.effects.Effect;
import tonegod.gui.effects.Effect.EffectDirection;
import tonegod.gui.effects.Effect.EffectEvent;
import tonegod.gui.effects.Effect.EffectType;
import tonegod.gui.framework.animation.Interpolation;

/**
 *
 * @author t0neg0d
 */
public class HUD extends AbstractAppState {
	Main main;
	Screen screen;
	Indicator muckMeter, gameMeter;
	TextElement muckText, gameText, timerDisplay, endGameMsg;
	TextElement ba1Label, ba2Label, ba3Label, ba4Label;
	RadioButtonGroup rbg;
	Element border;
	ButtonAdapter btnHose, btnSwat;
	Vector2f dim = new Vector2f();
	ButtonAdapter startGame, playAgain;
	ColorRGBA	startColor = new ColorRGBA(1,1,1,1),
				endColor = new ColorRGBA(1,0,0,1),
				finColor = new ColorRGBA();
	TextElement expDirDisplay;
	
	public HUD(Main main) {
		this.main = main;
		this.screen = main.getScreen();
		initHUD();
	}
	
	private void initHUD() {
		float ratio = 89f/243f;
		float indSize = 0.4f;
		
		Texture tex = main.getTextureManager().getTexture(TextureKey.ATLAS);
		
		dim.set(screen.getWidth()*indSize,screen.getWidth()*indSize*ratio);
		
		muckMeter = new Indicator(
			screen,
			new Vector2f(0,screen.getHeight()-dim.y),
			dim,
			Orientation.HORIZONTAL
		) {
			@Override
			public void onChange(float currentValue, float currentPercentage) {
				muckText.setText((int)currentPercentage + "%");
			}
		};
		muckMeter.getIndicatorElement().setTextureAtlasImage(
				tex,
				main.getTextureManager().getGUIRegion(RegionKey.IND_MUCK_AM)
		);
		muckMeter.getIndicatorElement().setAlphaMap(main.getTextureManager().getGUIRegion(RegionKey.IND_MUCK_AM));
		muckMeter.getOverlayElement().setTextureAtlasImage(
				tex,
				main.getTextureManager().getGUIRegion(RegionKey.IND_MUCK_OL)
		);
		muckMeter.setIsMovable(false);
		muckMeter.setIsResizable(false);
		muckMeter.setIgnoreMouse(true);
		muckMeter.setIndicatorColor(ColorRGBA.Green);
		muckMeter.setReverseDirection(true);
		muckText = this.getTextLabel(UIDUtil.getUID(), dim, "0%");
		muckMeter.addChild(muckText);
		muckMeter.setMaxValue(100);
		muckMeter.setCurrentValue(0);
		
		gameMeter = new Indicator(
			screen,
			new Vector2f(screen.getWidth()-dim.x,screen.getHeight()-dim.y),
			dim,
			Orientation.HORIZONTAL
		) {
			@Override
			public void onChange(float currentValue, float currentPercentage) {
				gameText.setText((int)currentValue + "/" + main.getLevelLoader().getCurrentScene().winTotal);
			}
		};
		gameMeter.getIndicatorElement().setTextureAtlasImage(
				tex,
				main.getTextureManager().getGUIRegion(RegionKey.IND_GAME_AM)
		);
		gameMeter.getIndicatorElement().setAlphaMap(main.getTextureManager().getGUIRegion(RegionKey.IND_GAME_AM));
		gameMeter.getOverlayElement().setTextureAtlasImage(
				tex,
				main.getTextureManager().getGUIRegion(RegionKey.IND_GAME_OL)
		);
		gameMeter.setIsMovable(false);
		gameMeter.setIsResizable(false);
		gameMeter.setIgnoreMouse(true);
		gameMeter.setIndicatorColor(ColorRGBA.Orange);
		gameText = this.getTextLabel(UIDUtil.getUID(), dim, "0/" + main.getLevelLoader().getCurrentScene().winTotal);
		gameMeter.addChild(gameText);
		gameMeter.setMaxValue(main.getLevelLoader().getCurrentScene().winTotal);
		gameMeter.setCurrentValue(0);
		
		rbg = new RadioButtonGroup(screen) {
			@Override
			public void onSelect(int index, Button value) {
				switch (index) {
					case 0:
						main.getHose().activateHose(true);
						break;
					case 1:
						main.getHose().activateHose(false);
						break;
				}
			}
		};
		
		float spacer = 4*main.getScaleManager().getGameScale();
		float btnRatio = 89f/59f;
		float btnWidth = screen.getWidth()-(screen.getWidth()*(indSize*2))+(spacer*2);
		btnWidth /= 2;
		
		dim.set(btnWidth,btnWidth*btnRatio);
		
		btnHose = new ButtonAdapter(screen, "btnHose", new Vector2f(muckMeter.getWidth()-spacer,screen.getHeight()-dim.y), dim, Vector4f.ZERO, null);
		btnHose.setTextureAtlasImage(tex, main.getTextureManager().getGUIRegion(RegionKey.BTN_HOSE_U));
		btnHose.setButtonHoverInfo(main.getTextureManager().getGUIRegion(RegionKey.BTN_HOSE_H),ColorRGBA.White);
		btnHose.setButtonPressedInfo(main.getTextureManager().getGUIRegion(RegionKey.BTN_HOSE_D),ColorRGBA.White);
		
		btnSwat = new ButtonAdapter(screen, "btnSwat", new Vector2f(btnHose.getX()+dim.x,screen.getHeight()-dim.y), dim, Vector4f.ZERO, null);
		btnSwat.setTextureAtlasImage(tex, main.getTextureManager().getGUIRegion(RegionKey.BTN_SWAT_U));
		btnSwat.setButtonHoverInfo(main.getTextureManager().getGUIRegion(RegionKey.BTN_SWAT_H),ColorRGBA.White);
		btnSwat.setButtonPressedInfo(main.getTextureManager().getGUIRegion(RegionKey.BTN_SWAT_D),ColorRGBA.White);
		
		rbg.addButton(btnHose);
		rbg.addButton(btnSwat);
		
		float btnBdrRatio = 143f/128f;
		float btnBdrWidth = screen.getWidth()-(screen.getWidth()*(indSize*2));
		
		dim.set(btnBdrWidth,btnBdrWidth*btnBdrRatio);
		
		border = new Element(screen, UIDUtil.getUID(), new Vector2f(muckMeter.getWidth()-(btnBdrWidth-(indSize*2)),screen.getHeight()-dim.y), dim, Vector4f.ZERO, null);
		border.setTextureAtlasImage(tex, main.getTextureManager().getGUIRegion(RegionKey.BTN_BORDER));
		
		timerDisplay = getTextLabel("timerDisplay", new Vector2f(screen.getWidth(),screen.getHeight()/4), "0:00");
		timerDisplay.setFontSize(60*main.getScaleManager().getFontScale());
		timerDisplay.setIgnoreMouse(true);
		
		endGameMsg = getTextLabel("endGameMsg", new Vector2f(screen.getWidth(),screen.getHeight()/4), "Game Over");
		endGameMsg.setPosition(0, screen.getHeight()/2-(endGameMsg.getAnimText().getLineHeight()/2));
		endGameMsg.setFontSize(60*main.getScaleManager().getFontScale());
		endGameMsg.setIgnoreMouse(true);
		
		startGame = new ButtonAdapter(screen, Vector2f.ZERO, new Vector2f(screen.getWidth()/2,screen.getHeight()/8)) {
			@Override
			public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
				main.startGame();
			}
		};
		TextElement sgLabel = getTextLabel("startGameLabel", startGame.getDimensions(), "New Game");
		sgLabel.setFontSize(30*main.getScaleManager().getFontScale());
		startGame.addChild(sgLabel);
		startGame.setPosition(screen.getWidth()/2-(startGame.getWidth()/2),screen.getHeight()/2-(startGame.getHeight()/2));
		Effect bounceIn = new Effect(EffectType.SlideIn, EffectEvent.Show, 1.5f);
		bounceIn.setEffectDirection(EffectDirection.Top);
		bounceIn.setInterpolation(Interpolation.bounceOut);
		startGame.addEffect(bounceIn);
		Effect fadeOut = new Effect(EffectType.FadeOut, EffectEvent.Hide, 0.5f);
		startGame.addEffect(fadeOut);
		
		
		playAgain = new ButtonAdapter(screen, Vector2f.ZERO, new Vector2f(screen.getWidth()/2,screen.getHeight()/8)) {
			@Override
			public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
				main.restartGame();
				main.startGame();
			}
		};
		TextElement paLabel = getTextLabel("playAgainLabel", playAgain.getDimensions(), "Play Again");
		paLabel.setFontSize(30*main.getScaleManager().getFontScale());
		playAgain.addChild(paLabel);
		playAgain.setPosition(screen.getWidth()/2-(playAgain.getWidth()/2),screen.getHeight()/2-(playAgain.getHeight()/2));
		bounceIn = new Effect(EffectType.SlideIn, EffectEvent.Show, 1.5f);
		bounceIn.setEffectDirection(EffectDirection.Top);
		bounceIn.setInterpolation(Interpolation.bounceOut);
		playAgain.addEffect(bounceIn);
		fadeOut = new Effect(EffectType.FadeOut, EffectEvent.Hide, 0.5f);
		playAgain.addEffect(fadeOut);
		
		btnHose.setIsEnabled(false);
		btnSwat.setIsEnabled(false);
		
		ButtonAdapter ba1 = new ButtonAdapter(screen, Vector2f.ZERO,
			new Vector2f(50*main.getScaleManager().getGameScale(),50*main.getScaleManager().getGameScale())) {
			@Override
			public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
				main.getCamTrans().moveToDeck(3);
			}
		};
		ba1.setTextureAtlasImage(
			main.getTextureManager().getTexture(TextureKey.ATLAS),
			main.getTextureManager().getGUIRegion(RegionKey.DECK_4)
		);
		ba1.clearAltImages();
		ba1Label = getTextLabel("ba1Label",ba1.getDimensions(),"0");
		ba1Label.setFontSize(20*main.getScaleManager().getFontScale());
		ba1.addChild(ba1Label);
		
		ButtonAdapter ba2 = new ButtonAdapter(screen, new Vector2f(ba1.getWidth(),0),
			ba1.getDimensions()) {
			@Override
			public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
				main.getCamTrans().moveToDeck(2);
			}
		};
		ba2.setTextureAtlasImage(
			main.getTextureManager().getTexture(TextureKey.ATLAS),
			main.getTextureManager().getGUIRegion(RegionKey.DECK_3)
		);
		ba2.clearAltImages();
		ba2Label = getTextLabel("ba2Label",ba1.getDimensions(),"0");
		ba2Label.setFontSize(20*main.getScaleManager().getFontScale());
		ba2.addChild(ba2Label);
		
		ButtonAdapter ba3 = new ButtonAdapter(screen, new Vector2f(0,ba1.getHeight()),
			ba1.getDimensions()) {
			@Override
			public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
				main.getCamTrans().moveToDeck(0);
			}
		};
		ba3.setTextureAtlasImage(
			main.getTextureManager().getTexture(TextureKey.ATLAS),
			main.getTextureManager().getGUIRegion(RegionKey.DECK_1)
		);
		ba3.clearAltImages();
		ba3Label = getTextLabel("ba3Label",ba1.getDimensions(),"0");
		ba3Label.setFontSize(20*main.getScaleManager().getFontScale());
		ba3.addChild(ba3Label);
		
		ButtonAdapter ba4 = new ButtonAdapter(screen, new Vector2f(ba1.getWidth(),ba1.getHeight()),
			ba1.getDimensions()) {
			@Override
			public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
				main.getCamTrans().moveToDeck(1);
			}
		};
		ba4.setTextureAtlasImage(
			main.getTextureManager().getTexture(TextureKey.ATLAS),
			main.getTextureManager().getGUIRegion(RegionKey.DECK_2)
		);
		ba4.clearAltImages();
		ba4Label = getTextLabel("ba4Label",ba1.getDimensions(),"0");
		ba4Label.setFontSize(20*main.getScaleManager().getFontScale());
		ba4.addChild(ba4Label);
		
		ButtonAdapter ba5 = new ButtonAdapter(screen, new Vector2f(0,ba1.getHeight()*2),
			ba1.getDimensions().subtract(0, ba1.getHeight()/2)) {
			@Override
			public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
				main.getCamTrans().prevDeck();
			}
		};
		ba5.setButtonIcon(ba1.getWidth()/2,ba1.getHeight()/2,screen.getStyle("Common").getString("arrowLeft"));
		ButtonAdapter ba6 = new ButtonAdapter(screen, new Vector2f(ba1.getWidth(),ba1.getHeight()*2),
			ba1.getDimensions().subtract(0, ba1.getHeight()/2)) {
			@Override
			public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
				main.getCamTrans().nextDeck();
			}
		};
		ba6.setButtonIcon(ba1.getWidth()/2,ba1.getHeight()/2,screen.getStyle("Common").getString("arrowRight"));
		
		expDirDisplay = getTextLabel("expDirDisplay",new Vector2f(screen.getWidth(),screen.getHeight()),"0");
		expDirDisplay.setFontSize(20*main.getScaleManager().getFontScale());
		expDirDisplay.setText(main.getLevelLoader().expDir);
		
	//	screen.addElement(expDirDisplay);
		
		screen.addElement(ba1);
		screen.addElement(ba2);
		screen.addElement(ba3);
		screen.addElement(ba4);
		screen.addElement(ba5);
		screen.addElement(ba6);
		
		screen.addElement(muckMeter, false);
		screen.addElement(gameMeter, false);
		screen.addElement(btnHose, false);
		screen.addElement(btnSwat, false);
		screen.addElement(timerDisplay, true);
		screen.addElement(startGame, true);
		screen.addElement(playAgain, true);
		startGame.showWithEffect();
	}
	
	public TextElement getTextLabel(String uid, Vector2f dim, String text) {
		TextElement el = new TextElement(screen, uid, Vector2f.ZERO, new Vector2f(dim), main.getDefaultFont()) {
			@Override
			public void onUpdate(float tpf) {  }
			@Override
			public void onEffectStart() {  }
			@Override
			public void onEffectStop() {  }
		};
		el.setIgnoreMouse(true);
		el.setIsResizable(false);
		el.setIsMovable(false);
		el.setTextWrap(LineWrapMode.NoWrap);
		el.setTextVAlign(VAlign.Center);
		el.setTextAlign(Align.Center);
		el.setFontSize(30*main.getScaleManager().getFontScale());
		el.setText(text);
		return el;
	}
	
	public void incMuckMeter(float amount) {
		muckMeter.setCurrentValue(muckMeter.getCurrentValue()+amount);
		if ((int)muckMeter.getCurrentValue() == 100) {
			main.endGame(Lost.MuckedUp);
		}
	}
	
	public void incGameMeter(float amount) {
		gameMeter.setCurrentValue(gameMeter.getCurrentValue()+amount);
		if ((int)gameMeter.getCurrentValue() == (int)gameMeter.getMaxValue()) {
			main.winGame();
		}
	}
	
	public void decMuckMeter(float amount) {
		muckMeter.setCurrentValue(muckMeter.getCurrentValue()-amount);
	}
	
	public void updateTimerDisplay(int time) {
		int mins = (int)(time/60);
		int secs = time%60;
		
		String displayMins = String.valueOf(mins) + ":";
		String displaySecs = String.valueOf(secs);
		if (displaySecs.length() == 1) displaySecs = "0" + displaySecs;
		String display = displayMins + displaySecs;
		
		timerDisplay.setText(display);
	}
	
	public void configGameMeter(int max) {
		gameMeter.setMaxValue(max);
	}
	
	public void runStartGame() {
		timerDisplay.show();
		if (startGame.getIsVisible())
			startGame.hideWithEffect();
		if (playAgain.getIsVisible())
			playAgain.hide();
		btnHose.setIsEnabled(true);
		btnSwat.setIsEnabled(true);
		rbg.setSelected(btnSwat);
	}
	
	public void runEndGame(Lost lost) {
		btnHose.setIsEnabled(false);
		btnSwat.setIsEnabled(false);
		switch (lost) {
			case Overrun:
				endGameMsg.setText("Overrun With Bugs!");
				break;
			case TimesUp:
				endGameMsg.setText("Out of Time");
				break;
			case MuckedUp:
				endGameMsg.setText("You Mucked Up...");
				break;
		}
		if (screen.getElementById(endGameMsg.getUID()) == null)
			screen.addElement(endGameMsg);
		endGameMsg.setPosition(0, screen.getHeight()/2-(endGameMsg.getAnimText().getLineHeight()/2));
		showPlayAgainBtn();
	}
	
	public void runWinGame() {
		btnHose.setIsEnabled(false);
		btnSwat.setIsEnabled(false);
		endGameMsg.setText("You won!");
		screen.addElement(endGameMsg);
		endGameMsg.setPosition(0, screen.getHeight()/2-(endGameMsg.getAnimText().getLineHeight()/2));
		showPlayAgainBtn();
	}
	
	private void showPlayAgainBtn() {
		playAgain.setPosition(screen.getWidth()/2-(playAgain.getWidth()/2),screen.getHeight()/2-(playAgain.getHeight()/2)-(endGameMsg.getAnimText().getLineHeight()/2));
		playAgain.showWithEffect();
	}
	public void reset() {
		screen.removeElement(endGameMsg);
		muckMeter.setCurrentValue(0);
		gameMeter.setCurrentValue(0);
		ba1Label.setText("0");
		ba1Label.setFontColor(startColor);
		ba2Label.setText("0");
		ba2Label.setFontColor(startColor);
		ba3Label.setText("0");
		ba3Label.setFontColor(startColor);
		ba4Label.setText("0");
		ba4Label.setFontColor(startColor);
	}
	
	public void updateBugCount(int index, int count) {
		switch (index) {
			case 0:
				ba3Label.setText(String.valueOf(count));
				finColor.interpolate(startColor, endColor, (float)count/25);
				ba3Label.setFontColor(finColor);
				break;
			case 1:
				ba4Label.setText(String.valueOf(count));
				finColor.interpolate(startColor, endColor, (float)count/25);
				ba4Label.setFontColor(finColor);
				break;
			case 2:
				ba2Label.setText(String.valueOf(count));
				finColor.interpolate(startColor, endColor, (float)count/25);
				ba2Label.setFontColor(finColor);
				break;
			case 3:
				ba1Label.setText(String.valueOf(count));
				finColor.interpolate(startColor, endColor, (float)count/25);
				ba1Label.setFontColor(finColor);
				break;
		}
	}
}
